package com.analysis.core;

import lombok.extern.slf4j.Slf4j;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class ConstantAnalyzer extends ClassVisitor {
    private final Map<String, Object> constants = new HashMap<>();
    private String className;

    public ConstantAnalyzer() {
        super(Opcodes.ASM9);
    }

    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        this.className = name.replace('/', '.');
        log.info("开始分析常量类: {}", className);
        super.visit(version, access, name, signature, superName, interfaces);
    }

    @Override
    public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
        // 只关注静态常量字段
        if ((access & Opcodes.ACC_STATIC) != 0 && (access & Opcodes.ACC_FINAL) != 0) {
            log.info("发现常量字段: {} = {}", name, value);
            if (value != null) {
                constants.put(name, value);
            }
        }
        return super.visitField(access, name, descriptor, signature, value);
    }

    public Map<String, Object> getConstants() {
        return new HashMap<>(constants);
    }

    public void reset() {
        log.info("重置常量分析器");
        constants.clear();
        className = null;
    }

    public boolean hasConstantChanges(Map<String, Object> otherConstants) {
        if (constants.size() != otherConstants.size()) {
            log.info("常量数量不同: 当前={}, 其他={}", constants.size(), otherConstants.size());
            return true;
        }

        for (Map.Entry<String, Object> entry : constants.entrySet()) {
            String name = entry.getKey();
            Object value = entry.getValue();
            Object otherValue = otherConstants.get(name);

            if (!value.equals(otherValue)) {
                log.info("常量值不同: {}={} vs {}", name, value, otherValue);
                return true;
            }
        }

        log.info("没有发现常量值变化");
        return false;
    }
}
